#include <stdio.h>  
#include <signal.h>
#include <iostream>
#include <sstream>

#include <zsystem/core/common/logdump.h>
#include <google/profiler.h>
#include "chatserver.h"
#include "chatserver_config.h"

#define CHATSERVER_PROGRAME_NAME "ChatServer"

#define CHATSERVER_VERSION_MAJOR    0
#define CHATSERVER_VERSION_MINOR    0
#define CHATSERVER_VERSION_MICRO    1
#define CHATSERVER_VERSION_INT      ( CHATSERVER_VERSION_MAJOR<<16 | CHATSERVER_VERSION_MINOR<<8 | CHATSERVER_VERSION_MICRO )
#define CHATSERVER_VERSION          "0.0.1"


Z_BOOL g_exit=Z_FALSE;
void
sigint(int s) 
{
  g_exit = true;
}
#pragma warning(disable:4996)
void setLogDestination(std::string& logPath)
{
  char buffer[1024];
  sprintf(buffer, "%s%s%s_%s_", logPath.c_str(), Z_PATH_SLASH, CHATSERVER_PROGRAME_NAME, "INFO");
  google::SetLogDestination(INFO, buffer);
  sprintf(buffer, "%s%s%s_%s_", logPath.c_str(), Z_PATH_SLASH, CHATSERVER_PROGRAME_NAME, "WARNING");
  google::SetLogDestination(WARNING, buffer);
  sprintf(buffer, "%s%s%s_%s_", logPath.c_str(), Z_PATH_SLASH, CHATSERVER_PROGRAME_NAME, "ERROR");
  google::SetLogDestination(ERROR, buffer);
#define BUFFER_SIZE 1024*1024*4
  char* test = (char*)Z_MALLOC(BUFFER_SIZE);
  for(int i = 0; i < BUFFER_SIZE; i++)
  {
    test[i] = (char)(i%265);
  }
  Z_FREE(test);

//  sprintf(buffer, "%s%s%s_cpu_profile", logPath.c_str(), Z_PATH_SLASH, CHATSERVER_PROGRAME_NAME);
//  ProfilerStart(buffer);
}
#pragma warning(default:4996)

int
main(int argc, char ** argv)
{
  google::InitGoogleLogging(argv[0]);

  std::string version(CHATSERVER_VERSION);
  google::SetVersionString(version);
  google::ParseCommandLineFlags(&argc, &argv, true);

  // Todo: Load config
  setLogDestination(FLAGS_LogPath);
#ifdef WIN32
  WSADATA wsaData;  
  DWORD Ret;  
  if ((Ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)  {  
    printf("WSAStartup failed with error %d\n", Ret);  
    return -1;  
  }
  CHECK_EQ(evthread_use_windows_threads(), 0);
#else
  CHECK_EQ(evthread_use_pthreads(), 0);
#endif
  event_set_log_callback(Z_LIBEVENT_LOG_PRINT);
  // Init object schemes
  std::stringstream objectSchemeStream, propSchemeStream;
  objectSchemeStream << FLAGS_ObjectDefineFilePath.c_str() << "objects.xml";
  propSchemeStream << FLAGS_ObjectDefineFilePath.c_str() << "props.xml";
  if ( !zsystem::objectFactory::init(objectSchemeStream.str().c_str(), propSchemeStream.str().c_str()))
  {
    printf("Initialize object scheme failed, file path: %s\n", FLAGS_ObjectDefineFilePath.c_str());  
    return -1;  
  }

  chatServer* server = Z_NEW(chatServer)();
  if ( !server-> start() )
  {
    LOG(ERROR) << "Start server error";
  }
  else
  {
    Z_DUMP("Server start running");
    signal(SIGINT, sigint);
    while(!g_exit)
    {
      zsystem::ssleep(5);
      server->traceLog();
      google::FlushLogFiles(INFO);
    }
    server->stop();
  }

  Z_SAFE_DELETE(server, ~chatServer);
#ifdef WIN32
  WSACleanup();  
#endif

  Z_DUMP("To shutdown google log and flags");
  google::ShutDownCommandLineFlags();
// To remove possibly leak warning of valgrind
  Z_DUMP("Server exit success");
  google::FlushLogFiles(INFO);
  google::ShutdownGoogleLogging();

  return 0;  
}  

